// 云函数入口文件
const cloud = require('wx-server-sdk');
const _ = require('lodash');
const moment = require('moment');
const random = require('random');

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
const db = cloud.database();
const command = db.command;

/**
 * 抽奖定时器
 * 任务: 发送开奖通知
 * @param {*} event 
 * @param {*} context 
 */
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext();
  const current_time = moment().format('YYYY-MM-DD HH:mm:ss');
  const lottery_list = await drawAction(current_time);
  // 1. 遍历抽奖活动
  lottery_list.forEach(async lottery => {
    // 2. 遍历活动的参与者，推送订阅消息
    lottery.participator_list.forEach(async item => {
      try {
        const result = await sendMsg(item.openid, lottery);
        console.log(item.openid, result);
      } catch (error) {
        console.error(error);
      }
    });
    // 3. 更新活动的消息推送状态 -> 更新抽奖信息为已发送订阅消息
    // db.collection('box_lottery').doc(lottery._id).update({ data: { send: 1 } }).catch(err => console.error(err));
  });
  return { code: 0, errmsg: `执行成功@${current_time}`, lottery_total: lottery_list.length };
}

/**
 * 开奖
 * 1. 查询状态为待开奖(status === 1)的抽奖活动
 * 2. 遍历查询符合开奖条件的抽奖活动，随机出来中奖者
 * 3. 更新查询符合开奖条件的抽奖活动状态，status 更新为已开奖（status === 2）
 * 4. 返回开奖的活动数组
 * @param {String} currentTime 当前时间
 */
async function drawAction(currentTime) {
  // 1. 查询符合开奖条件的抽奖活动
  const lotteryOpts = {
    status: 1,
    draw_time: command.lte(currentTime),
  };
  const lottery_res = await db.collection('box_lottery').aggregate().match(lotteryOpts).limit(10).end();
  // 2. 查询参与活动者
  const lottery_ids = _.map(lottery_res.list, '_id');
  const participateOpts = {
    lottery_id: command.in(lottery_ids)
  };
  const participate_res = await db.collection('box_lottery_participate').aggregate().match(participateOpts).limit(3000).end();
  // 3. 随机中奖者
  lottery_res.list.forEach(async lottery => {
    const participator_list = _.filter(participate_res.list, { lottery_id: lottery._id });
    lottery.participator_list = participator_list;
    const luckNumber = random.int(0, participator_list.length - 1);
    const { user_info, openid, lottery_code } = participator_list[luckNumber];
    try {
      const winner = { openid, lottery_code, ...user_info };
      await db.collection('box_lottery').doc(lottery._id).update({ data: { winner, status: 2 } });
    } catch (error) {
      console.error('Update box_lottery Error', error);
    }
  });
  return lottery_res.list;
}

/**
 * 发送订阅消息
 * @param {*} openid openid
 * @param {*} lottery 活动信息
 */
async function sendMsg(openid, lottery) {
  const message_data = {
    thing1: { value: lottery.name },
    time3: { value: lottery.draw_time },
    thing5: { value: '活动已开奖，请进入小程序查询' }
  };
  console.log(`订阅消息：${openid} <==>`, message_data);
  const result = await cloud.openapi.subscribeMessage.send({
    touser: openid,
    page: `pages/lottery/box?lottery_id=${lottery._id}`,
    data: message_data,
    templateId: lottery.tmplIds[0],
    miniprogram_state: 'developer'
  });
  return result;
}